package br.uefs.dexa.rfframework.gui.impl;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

import br.uefs.dexa.rfframework.db.annotation.XMLImageCLEFAnnotationFormatter;
import br.uefs.dexa.rfframework.db.map.MapDatabaseManager;
import br.uefs.dexa.rfframework.gui.interfaces.DigitalObjectPanel;
import br.uefs.dexa.rfframework.gui.interfaces.RFUserGUI;
import br.uefs.dexa.rfframework.gui.utils.ImagePanel;
import br.unicamp.ic.lis.rfframework.objects.DigitalObject;
import br.unicamp.ic.lis.rfframework.objects.IDigitalObject;

public class DigitalImagePanel extends DigitalObjectPanel {

	
	private static final long serialVersionUID = 4642638241652365131L;
	
	public static final int DEFAULT_VISUALIZATION_IMAGE_HEIGTH = 240;
	
	public static final int DEFAULT_QUERY_IMAGE_HEIGTH = 120;
	
	public static final int DEFAULT_RELEVANT_IMAGE_HEIGTH = 120;
	
	public static final int MODAL_IMAGE_HEIGTH = 470;
	
	public static final double MODAL_IMAGE_SCALE = 1;
	
	private static final int DETAIL_BUTTON_HEIGTH = 20;
	
	
	public static final Color QUERY_SELECTION_COLOR = Color.GREEN;
	public static final Color RELEVANT_SELECTION_COLOR = Color.ORANGE;
	
	//vertical and horizontal gaps
	private static final int V_GAP = 5;
	private static final int H_GAP = 5;
	
	//set border?
	private static final boolean BORDER = false;
	
	private Mode currentMode = Mode.NEUTRAL;
	
	private ImagePanel imagePanel;
	//private JButton detailButton;
	private JLabel detailButton;
	
	private int imageHeigth; 
	private int panelHeigth; 
	
	
	private enum Mode 
	{
		QUERY, RELEVANT, NEUTRAL
	}
	
	public DigitalImagePanel(IDigitalObject object, int heigth) 
	{
		super(object, heigth);
	}

	@Override
	protected void showObject(IDigitalObject object, int heigth) 
	{
		//imagePanel = new ImagePanel(getImagePath(), (DEFAULT_IMAGE_HEIGTH));
		this.imageHeigth = heigth;
		imagePanel = new ImagePanel(getImagePath(), heigth);
		
		//detailButton = new JButton();
		detailButton = new JLabel();
		
		detailButton.setSize(new Dimension(20, DETAIL_BUTTON_HEIGTH));		
		detailButton.setIcon(new ImageIcon("resources/icons/search_30.png"));
		
		setupComponents();
		setupPanel();
		addComponents();
	}
	
	private void setupPanel()
	{
		FlowLayout fl = new FlowLayout(FlowLayout.LEFT);
		fl.setVgap(V_GAP);
		fl.setHgap(H_GAP);
		setLayout(fl);
		
		panelHeigth = imageHeigth + detailButton.getHeight() + (7 * V_GAP);
		
		if(BORDER) {
			setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
		}
		
		setPreferredSize(new Dimension(imagePanel.getWidth() + (2 * H_GAP), panelHeigth)); //adds up to compensate gaps
	}
	

	private void addComponents()
	{
		add(imagePanel);
		add(detailButton);
	}
	
	@Override
	public void setSelected(boolean selected)
	{
		super.setSelected(selected);
		setCorrectColor();
	}
	
	@Override
	public void toogleSelected()
	{
		super.toogleSelected();
		setCorrectColor();
	}
	
	private void setCorrectColor()
	{
		switch (currentMode) 
		{
			case QUERY:
				SwingUtilities.invokeLater(new Runnable() {
					public void run() 
					{
						setBackground(QUERY_SELECTION_COLOR);
						revalidate();
						repaint();
					}
				});
		
				break;
			case RELEVANT:
				SwingUtilities.invokeLater(new Runnable() {
					public void run() 
					{
						setBackground(RELEVANT_SELECTION_COLOR);
						revalidate();
						repaint();
					}
				});
		
				break;
			case NEUTRAL:
				SwingUtilities.invokeLater(new Runnable() {
					public void run() 
					{
						setBackground(UIManager.getColor("control"));
						revalidate();
						repaint();
					}
				});
		
				break;

		}
	}
	
	
	
	@Override
	protected void setRelevantSelectionBehavior(RFUserGUI gui)
	{
		currentMode = Mode.RELEVANT;
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				addMouseListener(new java.awt.event.MouseAdapter() {
				    public void mouseEntered(java.awt.event.MouseEvent evt) {
				    	DigitalImagePanel.this.setBackground(RELEVANT_SELECTION_COLOR);
				        
				    }

				    public void mouseExited(java.awt.event.MouseEvent evt) {
				    	if(!DigitalImagePanel.this.isSelected())
				    		DigitalImagePanel.this.setBackground(UIManager.getColor("control"));
				    }
				    
				    public void mouseClicked(java.awt.event.MouseEvent evt) {

				    	DigitalImagePanel.this.toogleSelected();
				    	if(DigitalImagePanel.this.isSelected()) {
				    		gui.addRelevantObject(DigitalImagePanel.this.getDigitalObject());
				    	}
				    	else {
				    		gui.removeRelevantObject(DigitalImagePanel.this.getDigitalObject());
				    	}
				    	
				    	
				    }
				});
			}
		});
		
	}
	
	
	
	
	
	@Override
	protected void setQuerySelectionBehavior(RFUserGUI gui)
	{
		currentMode = Mode.QUERY;
		SwingUtilities.invokeLater(new Runnable() {
			public void run() 
			{
				addMouseListener(new java.awt.event.MouseAdapter() {
				    public void mouseEntered(java.awt.event.MouseEvent evt) {
				        DigitalImagePanel.this.setBackground(QUERY_SELECTION_COLOR);
				        //DigitalImagePanel.this.setToolTipText("Add to Query");
				        
				    }

				    public void mouseExited(java.awt.event.MouseEvent evt) {
				    	if(!DigitalImagePanel.this.isSelected())
				    		DigitalImagePanel.this.setBackground(UIManager.getColor("control"));
				    }
				    
				    public void mouseClicked(java.awt.event.MouseEvent evt) {

				    	DigitalImagePanel.this.toogleSelected();
				    	if(DigitalImagePanel.this.isSelected())
				    		gui.addQueryObject(DigitalImagePanel.this.getDigitalObject());
				    	else
				    		gui.removeQueryObject(DigitalImagePanel.this.getDigitalObject());
				    }
				});
			}
		});
		
	}
	
	
	@Override
	protected void foolBehavior(RFUserGUI gui)
	{
		SwingUtilities.invokeLater(new Runnable() {
			public void run() 
			{
				addMouseListener(new java.awt.event.MouseAdapter() {
				    public void mouseEntered(java.awt.event.MouseEvent evt) {
				        DigitalImagePanel.this.setBackground(Color.RED);
				        //DigitalImagePanel.this.setToolTipText("Add to Query");
				        
				    }

				    public void mouseExited(java.awt.event.MouseEvent evt) {
				    	if(!DigitalImagePanel.this.isSelected())
				    		DigitalImagePanel.this.setBackground(UIManager.getColor("control"));
				    }
				    
				    public void mouseClicked(java.awt.event.MouseEvent evt) {

				    	DigitalImagePanel.this.toogleSelected();
				    	
				    }
				});
			}
		});
		
	}
	
	
	@Override
	protected void resetBehavior()
	{
		currentMode = Mode.NEUTRAL;
		removeMouseListeners();
	}

	
	private void removeMouseListeners()
	{
		MouseListener[] ml = this.getMouseListeners();
		
		for (int i = 0; i < ml.length; i++) {
			
			MouseListener mouseListener = ml[i];
			
			try {
				
				if (!SwingUtilities.isEventDispatchThread()) {
				
					EventQueue.invokeAndWait(new Runnable() {
						public void run() 
						{
							removeMouseListener(mouseListener);			
							revalidate();
							repaint();
						}
					});
				
				} else {
					removeMouseListener(mouseListener);
					revalidate();
					repaint();
				}

			} catch (InvocationTargetException e) {
				e.printStackTrace();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} 
			
		}
	}
	
	private String getImagePath()
	{
		return MapDatabaseManager.getInstance().getImagePath(getObjectId());
	}
	
	private String getAnnotationPath()
	{
		return MapDatabaseManager.getInstance().getAnnotationPath(getObjectId());
	}
	
	
	private String getAnnotation()
	{
		//return MapDatabaseManager.getInstance().getAnnotation(getObjectId(), null);
		return MapDatabaseManager.getInstance().getAnnotation(getObjectId(), new XMLImageCLEFAnnotationFormatter());
	}
	
	private void setupComponents() 
	{
		
		detailButton.addMouseListener(new MouseListener() {

			@Override
			public void mouseClicked(MouseEvent e) {
				//detailButton.setBackground(Color.DARK_GRAY);
				showDetailDialog();
				
			}

			@Override
			public void mousePressed(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseEntered(MouseEvent e) {
				detailButton.setBorder(BorderFactory.createLineBorder(Color.BLACK));
				
			}

			@Override
			public void mouseExited(MouseEvent e) {
				detailButton.setBorder(BorderFactory.createEmptyBorder());
				
			}
			
			
		});
	}
	
	private void showDetailDialog()
	{
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		String imagePath = getImagePath();
		String annotation = getAnnotation();
		
		SwingUtilities.invokeLater(new Runnable() {
			public void run() 
			{
				JDialog dialog = new JDialog(null, "", Dialog.ModalityType.DOCUMENT_MODAL);
		    	JPanel modalPanel = new JPanel();
		    	JEditorPane textArea = new JEditorPane("text/html", "");
		    	textArea.setText(annotation);
		    	textArea.setEditable(false);
		    	
		    	modalPanel.setLayout(new BoxLayout(modalPanel, BoxLayout.PAGE_AXIS));
		    	modalPanel.add(new ImagePanel(imagePath, DigitalImagePanel.MODAL_IMAGE_SCALE));
		    	modalPanel.add(textArea);
		    	
		    	dialog.setModal(true);
		    	dialog.add(modalPanel);
		    	dialog.pack();
		    	
		    	  
		    	dialog.setLocation((screen.width )/2 - dialog.getWidth()/2 , (screen.height)/2 - dialog.getHeight()/2);
		    	dialog.setVisible(true);
		    	dialog.dispose();
			}
		});
		
	}

	

}
